﻿using EasyNet.Componets.Core.Types;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyNet.Componets.Core.Utils
{
    /// <summary>
    /// 时间Util
    /// </summary>
    public static class TimeUtil
    {
        private const string _timeZoneName = "TimeZone";

        #region ToUtc
        public static DateTime ToUtc(DateTime time, TimeConvertKindType convertKind)
        {
            var utcTime = time;
            if (time.Kind == DateTimeKind.Unspecified)
            {
                if (convertKind == TimeConvertKindType.Specify)
                {
                    utcTime = DateTime.SpecifyKind(time, DateTimeKind.Utc);
                }
                else
                {
                    utcTime = TimeZone.CurrentTimeZone.ToUniversalTime(time);
                }

            }
            else if (time.Kind == DateTimeKind.Local)
            {
                utcTime = time.ToUniversalTime();
            }
            return utcTime;
        }

        public static DateTime? ToUtc(DateTime? time, TimeConvertKindType convertKind)
        {
            var utcTime = time;
            if (time.HasValue)
            {
                if (time.Value.Kind == DateTimeKind.Unspecified)
                {
                    if (convertKind == TimeConvertKindType.Specify)
                    {
                        utcTime = DateTime.SpecifyKind(time.Value, DateTimeKind.Utc);
                    }
                    else
                    {
                        utcTime = TimeZone.CurrentTimeZone.ToUniversalTime(time.Value);
                    }
                }
                else if (time.Value.Kind == DateTimeKind.Local)
                {
                    utcTime = time.Value.ToUniversalTime();
                }
            }

            return utcTime;
        }
        #endregion

        #region ToLocal
        public static DateTime ToLocal(DateTime time, TimeConvertKindType convertKind)
        {
            var localTime = time;
            if (time.Kind == DateTimeKind.Unspecified)
            {
                if (convertKind == TimeConvertKindType.Specify)
                {
                    localTime = DateTime.SpecifyKind(time, DateTimeKind.Local);
                }
                else
                {
                    localTime = TimeZone.CurrentTimeZone.ToLocalTime(time);
                }

            }
            else if (time.Kind == DateTimeKind.Utc)
            {
                localTime = time.ToLocalTime();
            }
            return localTime;
        }

        public static DateTime? ToLocal(DateTime? time, TimeConvertKindType convertKind)
        {
            var localTime = time;
            if (time.HasValue)
            {
                if (time.Value.Kind == DateTimeKind.Unspecified)
                {
                    if (convertKind == TimeConvertKindType.Specify)
                    {
                        localTime = DateTime.SpecifyKind(time.Value, DateTimeKind.Local);
                    }
                    else
                    {
                        localTime = TimeZone.CurrentTimeZone.ToLocalTime(time.Value);
                    }
                }
                else if (time.Value.Kind == DateTimeKind.Local)
                {
                    localTime = time.Value.ToLocalTime();
                }
            }

            return localTime;
        }
        #endregion


        #region 获取时间戳
        public static long GetTimeStamp()
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (DateTime.Now.Ticks - startTime.Ticks) / 10000;   //除10000调整为13位      
            return t;
        }

        public static long GetTimeStamp(DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000调整为13位      
            return t;
        }

        public static DateTime TimeStampToDateTime(long timeStamp)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区

            if (timeStamp.ToString().Length == 13)
            {
                return startTime.AddMilliseconds(timeStamp);
            }
            else if (timeStamp.ToString().Length == 10)
            {
                return startTime.AddSeconds(timeStamp);
            }
            return DateTime.Now;
        }
        #endregion

        #region US Time To Loacl
        public static DateTime? USToLocal(string usTime, string usTimeFormat, string usTimeZone, bool isDefualtCurrentTime)
        {
            if (string.IsNullOrEmpty(usTime)) return null;
            DateTime? localTime = null;
            try
            {
                if (isDefualtCurrentTime)
                {
                    localTime = DateTime.Now;
                }
                var timeZoneDic = GetUSTimeZone();
                if (timeZoneDic.ContainsKey(usTimeZone.ToUpper()))
                {
                    DateTime convertTime;
                    var diffHours = timeZoneDic[usTimeZone];
                    usTimeFormat = usTimeFormat.Replace(_timeZoneName, usTimeZone);
                    if (DateTime.TryParseExact(usTime, usTimeFormat, CultureInfo.InvariantCulture,
                       DateTimeStyles.None, out convertTime))
                    {
                        localTime = convertTime.AddHours(diffHours);
                    }
                }
            }
            catch
            {

            }

            return ToLocal(localTime, TimeConvertKindType.Specify);
        }

        private static Dictionary<string, int> GetUSTimeZone()
        {
            var dic = new Dictionary<string, int>();
            //美国标准时间与北京时间时差
            dic.Add("HST", 18);
            dic.Add("AKST", 17);
            dic.Add("PST", 16);
            dic.Add("MST", 15);
            dic.Add("CST", 14);
            dic.Add("EST", 13);
            //美国夏季时间与北京时间时差
            dic.Add("HDT", 17);
            dic.Add("AKDT", 16);
            dic.Add("PDT", 15);
            dic.Add("MDT", 14);
            dic.Add("CDT", 13);
            dic.Add("EDT", 12);


            return dic;
        }
        #endregion


    }
}
